package cn.sciento.farm.devicemanager.gateway.uplink.service.sensor;

import cn.sciento.farm.devicemanager.common.constant.AlarmConstant;
import cn.sciento.farm.devicemanager.common.constant.RedisConstant;
import cn.sciento.farm.devicemanager.common.util.RedisUtil;
import cn.sciento.farm.devicemanager.dao.entity.DevAlarm;
import cn.sciento.farm.devicemanager.dao.entity.DevAlarmLog;
import cn.sciento.farm.devicemanager.dao.entity.DevCollection;
import cn.sciento.farm.devicemanager.dao.entity.ResAlarmPerson;
import cn.sciento.farm.devicemanager.dao.model.AlarmForm;
import cn.sciento.farm.devicemanager.gateway.config.AlarmProperties;
import cn.sciento.farm.devicemanager.gateway.uplink.service.sensor.alarm.AlarmSendService;
import cn.sciento.farm.devicemanager.service.AlarmLogService;
import cn.sciento.farm.devicemanager.service.AlarmService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.Date;
import java.util.List;
import java.util.Map;

@Service
public class AlarmDisposeService {

    Logger logger = LoggerFactory.getLogger(getClass());

    @Autowired
    private AlarmService alarmService;

    @Autowired
    private Map<String, AlarmSendService> alarmSendServiceMap;

    @Autowired
    private AlarmLogService alarmLogService;

    @Autowired
    private AlarmProperties alarmProperties;

    // 没有实现发送的策略
    public void dispatch(DevCollection devCollection){
        List<AlarmForm> alarmFormList = alarmService.getByCollectionId(devCollection.getId());
        if (alarmFormList == null || alarmFormList.size() == 0) {
            return;
        }
        for (AlarmForm deviceTrigger : alarmFormList) {
            DevAlarmLog devAlarmLog = judgeTrigger(devCollection, deviceTrigger);
            if (devAlarmLog != null) {
                String haveSend = RedisUtil.getCacheStr(RedisConstant.TRIGGER_INTERVAL_PREFIX + deviceTrigger.getId());
                if (haveSend == null) {
                    logger.info(devAlarmLog.toString());
                    sendTriggerInfo(devAlarmLog, deviceTrigger);
                    RedisUtil.putCacheStr(RedisConstant.TRIGGER_INTERVAL_PREFIX + deviceTrigger.getId(), "", (long) (alarmProperties.getInterval() * 60));
                }
            }
        }
    }

    void sendTriggerInfo(DevAlarmLog deviceTriggerLog, AlarmForm alarmForm) {
        List<ResAlarmPerson> personList = alarmForm.getPersonList();
        if (personList == null || personList.size() == 0) {
            return;
        }
        String service = AlarmConstant.SERVICE_PREFIX + deviceTriggerLog.getAlarmSendType();
        AlarmSendService alarmSendService = alarmSendServiceMap.get(service);

        if (alarmSendService == null) {
            logger.info("没有相关的service：" + service);
            return;
        }
        alarmSendService.send(deviceTriggerLog, personList);
    }

    private DevAlarmLog judgeTrigger(DevCollection collection, AlarmForm devAlarm) {
        int alarmType = devAlarm.getType();
        String threshold = devAlarm.getThreshold();
        float data = collection.getLastData();
        boolean alarm = false;
        String content = "";
        switch (alarmType) {
            case AlarmConstant.TYPE_ON:
                if (data == 1) {
                    alarm = true;
                    content = AlarmConstant.TEMPLATE_ON;
                }
                break;
            case AlarmConstant.TYPE_OFF:
                if (data == 0) {
                    alarm = true;
                    content = AlarmConstant.TEMPLATE_OFF;
                }
                break;
            case AlarmConstant.TYPE_GREATER:
                float greaterRange = Float.parseFloat(threshold);
                if (data > greaterRange) {
                    alarm = true;
                    content = AlarmConstant.TEMPLATE_GREATER.replace("%s", greaterRange + "");
                }
                break;
            case AlarmConstant.TYPE_LESS:
                float lessRange = Float.parseFloat(threshold);
                if (data < lessRange) {
                    alarm = true;
                    content = AlarmConstant.TEMPLATE_LESS.replace("%s", lessRange + "");
                }
                break;
            case AlarmConstant.TYPE_LESS_GREATER:
                String[] thresholdList = threshold.split("#");
                if (thresholdList.length != 2) {
                    return null;
                }
                float lessA = Float.parseFloat(thresholdList[0]);
                float greaterB = Float.parseFloat(thresholdList[1]);

                if (data < lessA || data > greaterB) {
                    alarm = true;
                    content = AlarmConstant.TEMPLATE_LESS_GREATER.replace("%s", lessA + "").replace("%d", greaterB + "");
                }
                break;
            case AlarmConstant.TYPE_GREATER_LESS:
                String[] greaterThresholdList = threshold.split("#");
                if (greaterThresholdList.length != 2) {
                    return null;
                }
                float greaterA = Float.parseFloat(greaterThresholdList[0]);
                float lessB = Float.parseFloat(greaterThresholdList[1]);

                if (data > greaterA && data < lessB) {
                    alarm = true;
                    content = AlarmConstant.TEMPLATE_GREATER_LESS.replace("%s", greaterA + "").replace("%d", lessB + "");
                }
                break;
            default:
        }
        if (alarm) {
            DevAlarmLog devAlarmLog = new DevAlarmLog();
            devAlarmLog.setAlarmType(devAlarm.getType());
            devAlarmLog.setAlarmId(devAlarm.getId());
            devAlarmLog.setAlarmName(devAlarm.getName());
            devAlarmLog.setAlarmThreshold(devAlarm.getThreshold());
            devAlarmLog.setAlarmSendType(devAlarm.getAlarmType());
            devAlarmLog.setActualValue(data);
            devAlarmLog.setContent(content);
            devAlarmLog.setCollectionId(collection.getId());
            devAlarmLog.setCollectionName(collection.getName());
            devAlarmLog.setCreateTime(System.currentTimeMillis());
            devAlarmLog.setType(AlarmConstant.LOG_ALARM);
            devAlarmLog.setStatus(0);
            devAlarmLog.setTenantId(devAlarm.getTenantId());
            devAlarmLog.setAreaId(devAlarm.getAreaId());
            alarmLogService.create(devAlarmLog);
            return devAlarmLog;
        }
        return null;


    }
}
